﻿using MudBlazor.Utilities;
using MXERP.Blazor.Interop;

namespace MXERP.Blazor.Components
{
    public partial class Tooltip : MudComponentBase, IOutsideEventJsCallback
    {
        private Origin _anchorOrigin;
        private Origin _transformOrigin;
        private bool _popoverIsHover;

        protected string ContainerClass => new CssBuilder("mud-tooltip-root")
            .AddClass("mud-tooltip-inline", Inline)
            .AddClass(RootClass)
            .Build();

        protected string Classname => new CssBuilder("mud-tooltip")
            .AddClass("d-flex")
            .AddClass("mud-tooltip-default", Color == Color.Default)
            .AddClass($"mud-tooltip-{ConvertPlacement().ToDescriptionString()}")
            .AddClass("mud-tooltip-arrow", Arrow)
            .AddClass($"mud-border-{Color.ToDescriptionString()}", Arrow && Color != Color.Default)
            .AddClass($"mud-theme-{Color.ToDescriptionString()}", Color != Color.Default)
            .AddClass(Class)
            .Build();
        [Inject]
        private OutsideMouseEnterJsInterop OutsideMouseEnterJsInterop { get; set; } = default!;
        [CascadingParameter(Name = "RightToLeft")]
        public bool RightToLeft { get; set; }

        /// <summary>
        /// The color of the component. It supports the theme colors.
        /// </summary>
        [Parameter]
        public Color Color { get; set; } = Color.Default;

        /// <summary>
        /// Sets the text to be displayed inside the tooltip.
        /// </summary>
        [Parameter]
        public string? Text { get; set; } = string.Empty;

        /// <summary>
        /// If true, an arrow will be displayed pointing towards the content from the tooltip.
        /// </summary>
        [Parameter]
        public bool Arrow { get; set; } = true;

        /// <summary>
        /// Tooltip placement.
        /// </summary>
        [Parameter]
        public Placement Placement { get; set; } = Placement.Bottom;

        /// <summary>
        /// Child content of component.
        /// </summary>
        [Parameter]
        public RenderFragment? ChildContent { get; set; }

        /// <summary>
        /// Tooltip content. May contain any valid html
        /// </summary>
        [Parameter]
        public RenderFragment? TooltipContent { get; set; }

        /// <summary>
        /// Determines if this component should be inline with it's surrounding (default) or if it should behave like a block element.
        /// </summary>
        [Parameter]
        public bool Inline { get; set; } = true;

        /// <summary>
        /// Styles applied directly to root component of the tooltip
        /// </summary>
        [Parameter]
        public string? RootStyle { get; set; }

        /// <summary>
        /// Classes applied directly to root component of the tooltip
        /// </summary>
        [Parameter]
        public string? RootClass { get; set; }

        [Parameter]
        public bool Disabled { get; set; }

        public MudPopover Popover { get; set; } = default!;
        public ElementReference Element { get; set; }
        private bool _open;

        private async Task HandlePointerEnterAsync()
        {
            if (!Disabled)
            {
                await OutsideMouseEnterJsInterop.Initialize(this, Element, Popover.Id);
                _open = true;
            }  
        }

        private  void HandlePointerLeaveAsync()
        {
            if (!Disabled)
            {
                _open = false;
            }
        }

        public Task HandleOnOutsideEventAsync()
        {
            _open = false;
            StateHasChanged();
            return Task.CompletedTask;
        }

        private Origin ConvertPlacement()
        {
            if (Placement == Placement.Bottom)
            {
                _anchorOrigin = Origin.BottomCenter;
                _transformOrigin = Origin.TopCenter;

                return Origin.BottomCenter;
            }

            if (Placement == Placement.Top)
            {
                _anchorOrigin = Origin.TopCenter;
                _transformOrigin = Origin.BottomCenter;

                return Origin.TopCenter;
            }

            if (Placement == Placement.Left || (Placement == Placement.Start && !RightToLeft) || (Placement == Placement.End && RightToLeft))
            {
                _anchorOrigin = Origin.CenterLeft;
                _transformOrigin = Origin.CenterRight;

                return Origin.CenterLeft;
            }

            if (Placement == Placement.Right || (Placement == Placement.End && !RightToLeft) || (Placement == Placement.Start && RightToLeft))
            {
                _anchorOrigin = Origin.CenterRight;
                _transformOrigin = Origin.CenterLeft;

                return Origin.CenterRight;
            }

            return Origin.BottomCenter;
        }
    }
}
